package me.magicall.db.sql;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;

import me.magicall.util.ArrayUtil;
import me.magicall.util.LanguageLabelConverter;
import me.magicall.util.kit.Kits;

/**
 * 可以跟随一个元素列表的sql元素,比如select,from,where
 * 
 * @author MaGiCalL
 * @param <E>
 */
public abstract class FollowingElements<E extends SqlElement> extends SqlElementTemplate {

	/**
	 * sql前缀,比如select,from,where,注意已经在前后带有空格
	 */
	private final String prefix;
	private E firstElement;
	private List<E> otherElements;

	protected FollowingElements() {
		this(null);
	}

	protected FollowingElements(final E firstElement) {
		super();
		this.prefix = initPrefix();
		this.firstElement = firstElement;
	}

	protected String initPrefix() {
		final String[] ss = LanguageLabelConverter.CAMEL.splitWords(getClass().getSimpleName());
		final StringBuilder sb = new StringBuilder(" ");
		for (final String s : ss) {
			sb.append(s).append(" ");
		}
		return sb.toString();
	}

	public void add(final E element) {
		if (firstElement == null) {
			firstElement = element;
		} else {
			getOtherElements().add(element);
		}
	}

	public void add(final E... elements) {
		if (ArrayUtil.isEmpty(elements)) {
			return;
		}
		add(Arrays.asList(elements));
	}

	public void add(final Collection<E> elements) {
		if (Kits.COLL.isEmpty(elements)) {
			return;
		}
		if (firstElement == null) {
			final Iterator<E> i = elements.iterator();
			firstElement = i.next();
			final List<E> list = getOtherElements();
			while (i.hasNext()) {
				list.add(i.next());
			}
		} else {
			getOtherElements().addAll(elements);
		}
	}

	@Override
	public StringBuilder appendTo(final StringBuilder sb) {
		final E firstElement = getFirstElement();
		if (firstElement == null) {
			return sb;
		}
		sb.append(" ").append(getPrefix());
		firstElement.appendTo(sb);
		int index = 0;
		for (final E e : getOtherElements()) {
			sb.append(elementConnector(e, index));
			e.appendTo(sb);
			++index;
		}
		return sb.append(" ");
	}

	/**
	 * 元素间的连接符
	 * 
	 * @return
	 */
	protected String elementConnector(final E curElement, final int index) {
		return ",";
	}

	protected List<E> getOtherElements() {
		if (otherElements == null) {
			otherElements = new ArrayList<E>();
		}
		return otherElements;
	}

	public E getFirstElement() {
		return firstElement;
	}

	public void setFirstElement(final E firstElement) {
		this.firstElement = firstElement;
	}

	/**
	 * there are already blank at start and end
	 * 
	 * @return
	 */
	protected String getPrefix() {
		return prefix;
	}
}
